package io.gitee.duxiuhuan.mailbox.service.impl;

import io.gitee.duxiuhuan.mailbox.database.MessageMapper;
import io.gitee.duxiuhuan.mailbox.database.entries.MessageInfo;
import io.gitee.duxiuhuan.mailbox.outter.QueryTableUtils;
import io.gitee.duxiuhuan.mailbox.service.inter.MessageManager;
import lombok.extern.slf4j.Slf4j;
import org.postgresql.util.PSQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.SQLSyntaxErrorException;
import java.util.List;

@Slf4j
@Service
public class MessageManagerService implements MessageManager {
    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    QueryTableUtils queryTableUtils;

    @Override
    public List<MessageInfo> selectMessage(String tableName, MessageInfo messageInfo) {
        return this.selectMessageWithRetry(tableName, messageInfo,1);
    }

    private List<MessageInfo> selectMessageWithRetry(String tableName, MessageInfo messageInfo, int attempt) {
        try {
            // 尝试查询数据
            return messageMapper.selectMessage(tableName, messageInfo);
        } catch (Exception e) {
            if (isTableNotExistException(e,tableName)) { // 判断异常是否是“表不存在”
                if (attempt == 2) {
                    log.error("目标用户数据库表不存在,且创建数据库表失败",e);
                    throw new RuntimeException("目标用户数据库表不存在,且创建数据库表失败", e);
                }
                try {
                    log.warn("目标用户数据库表不存在，开始尝试创建");
                    queryTableUtils.createTable(tableName);
                } catch (Exception createEx) {
                    log.error("创建数据库表失败",createEx);
                    throw new RuntimeException("创建数据库表失败", createEx);
                }
                // 再次递归尝试查询
                return selectMessageWithRetry(tableName, messageInfo, attempt + 1);
            } else {
                // 如果不是表不存在的异常，直接抛出
                throw new RuntimeException("查询数据失败", e);
            }
        }
    }

    @Override
    public Boolean insertMessages(String tableName, List<MessageInfo> messageInfoList) {
        return this.insertMessagesWithRetry(tableName, messageInfoList, 1) != 0 ? true : false;
    }

    private Integer insertMessagesWithRetry(String tableName, List<MessageInfo> messageInfoList, int attempt) {
        try {
            // 尝试查询数据
            return messageMapper.insertMessages(tableName, messageInfoList);
        } catch (Exception e) {
            if (isTableNotExistException(e,tableName)) { // 判断异常是否是“表不存在”
                if (attempt == 2) {
                    log.error("目标用户数据库表不存在,且创建数据库表失败",e);
                    throw new RuntimeException("目标用户数据库表不存在,且创建数据库表失败", e);
                }
                try {
                    log.warn("目标用户数据库表不存在，开始尝试创建");
                    queryTableUtils.createTable(tableName);
                } catch (Exception createEx) {
                    log.error("创建数据库表失败",createEx);
                    throw new RuntimeException("创建数据库表失败", createEx);
                }
                // 再次递归尝试查询
                return insertMessagesWithRetry(tableName, messageInfoList, attempt + 1);
            } else {
                // 如果不是表不存在的异常，直接抛出
                throw new RuntimeException("查询数据失败", e);
            }
        }
    }

    @Override
    public Boolean deleteMessageById(String tableName, Long id) {
        return this.deleteMessageByIdWithRetry(tableName, id ,1) != 0 ? true : false;
    }

    private Integer deleteMessageByIdWithRetry(String tableName, Long id, int attempt) {
        try {
            // 尝试查询数据
            return messageMapper.deleteMessageById(tableName, id);
        } catch (Exception e) {
            if (isTableNotExistException(e,tableName)) { // 判断异常是否是“表不存在”
                if (attempt == 2) {
                    log.error("目标用户数据库表不存在,且创建数据库表失败",e);
                    throw new RuntimeException("目标用户数据库表不存在,且创建数据库表失败", e);
                }
                try {
                    log.warn("目标用户数据库表不存在，开始尝试创建");
                    queryTableUtils.createTable(tableName);
                } catch (Exception createEx) {
                    log.error("创建数据库表失败",createEx);
                    throw new RuntimeException("创建数据库表失败", createEx);
                }
                // 再次递归尝试查询
                return deleteMessageByIdWithRetry(tableName, id, attempt + 1);
            } else {
                // 如果不是表不存在的异常，直接抛出
                throw new RuntimeException("查询数据失败", e);
            }
        }
    }
    
    private boolean isTableNotExistException(Throwable exception,String tableName) {
        Throwable cause = exception.getCause(); // 获取底层异常
        while (cause != null) {
            //查询数据库是否存在
            List<String> strings = queryTableUtils.selectTable(tableName);
            if (strings.isEmpty()) {
                return true;
            }
        }
        return false;
    }
}
